#ifndef NETLIB_BLOCKINGQUEUE_H
#define NETLIB_BLOCKINGQUEUE_H

// 无界缓冲区

#include "Condition.h"
#include "Mutex.h"

#include <deque>
#include <assert.h>

namespace netlib
{

template<typename T>
class BlockingQueue : noncopyable // 不可拷贝
{
public:
    BlockingQueue() : mutex_(),notEmpty_(mutex_),queue_()
    { }

    void put(const T& x) // 从队列中尾插元素
    {
        MutexLockGuard lock(mutex_);
        queue_.push_back(x);
        notEmpty_.notify();
    }

    void put(T&& x) // 从队列中尾插元素：移动语义（右值引用）
    {
        MutexLockGuard lock(mutex_);
        queue_.push_back(std::move(x));
        notEmpty_.notify(); // 通知工作线程调用取出函数进行处理
    }

    T take() // 从队列中取出元素
    {
        MutexLockGuard lock(mutex_);
        while (queue_.empty())
            notEmpty_.wait();
        assert(!queue_.empty());
        T front(std::move(queue_.front()));
        queue_.pop_front();
        return front;
    }

    size_t size() const // 返回队列中元素个数
    {
        MutexLockGuard lock(mutex_);
        return queue_.size();
    }

private:
    mutable MutexLock mutex_;                           // (易变的)互斥锁
    Condition         notEmpty_ GUARDED_BY(mutex_);     // 条件变量（不为空）
    std::deque<T>     queue_ GUARDED_BY(mutex_);        // 标准库容器

}; // class BlockingQueue end

} // namespace netlib end

#endif